<script setup>
import {defineProps, reactive, watchEffect} from "vue";
import {clearAndPushAll} from "@/utils/ArrayUtil";

/**
 * //todo 20240314 整个逻辑应该放在YoudaoLijuPatternMarkingTemp.js set pickedPhrasesTopMost pickedPhrases1 pickedWordsTopMost 时调用
 * 作为 YoudaoLijuPatternMarkingTemp 的method
 * 分段，pickedPhrasesTopMost pickedPhrases1 改变时分别构造splits。 pickedWordsTopMost改变时构造split的subsplits
 */


import {intersection, difference, union, orderBy} from "lodash-unified";
import {YoudaoLijuPatternMarkingTemp} from "@/dtos/YoudaoLijuPatternMarkingTemp";

const theProps = defineProps(["theLijuEntry"]);

// console.log("PhraseOWordSettledSingleEntryView.vue");


let theEng = theProps.theLijuEntry.eng;

let topMostResultArr = [];
let top1ResultArr = [];
let resultIntersected = [];
let orderedAllPhrasesSplitsArr = [];
let finalOrderedSplitsArr = reactive([]);

watchEffect(() => {

    // console.log("PhraseOWordSettledSingleEntryView.vue watchedEffect");
    let startdate = new Date();
    let enddate;
    function buildPhrasesIdxArr(phraseTop) {
        let mappedArrs = phraseTop.map((entry, index, array) => {
            let arr = [];
            for (let i = entry.startWordMark.startIdx; i < entry.endWordMark.startIdx + entry.endWordMark.word.length; i++) {
                arr.push(i);
            }
            return arr;

            // console.log(theEng.substring(arr[0],arr[arr.length-1]));
        })

        let flatedArr = mappedArrs.reduce((previousArr, currentArr, currentIndex, array) => {
            return previousArr.concat(currentArr);
        });
        return {mappedArrs: mappedArrs, flatedArr: flatedArr}
    }

    if (theProps.theLijuEntry.pickedPhrases1 && theProps.theLijuEntry.pickedPhrases1?.length > 0) {
        let {
            mappedArrs: topMostMappedArrs,
            flatedArr: topMostReducedArr
        } = buildPhrasesIdxArr([...theProps.theLijuEntry.pickedPhrasesTopMost]);
        let {
            mappedArrs: top1MappedArrs,
            flatedArr: top1ReducedArr
        } = buildPhrasesIdxArr(theProps.theLijuEntry.pickedPhrases1);
        enddate = new Date();
        // console.log("ms elapsed 1:", Math.abs(startdate.getTime() - enddate.getTime()));
        let topMostTop1Intersected = intersection(topMostReducedArr, top1ReducedArr);
        let topMostdifferencedReduced = difference(topMostReducedArr, topMostTop1Intersected);
        let top1DifferencedReduced = difference(top1ReducedArr, topMostTop1Intersected);

        let topMostResutlArrs = [];
        topMostMappedArrs.forEach(theArr => {
            let inters = intersection(theArr, topMostdifferencedReduced);
            if (inters && inters.length > 0) {
                topMostResutlArrs.push(inters);
            }
        })

        let top1ResutlArrs = [];
        top1MappedArrs.forEach(theArr => {
            let inters = intersection(theArr, top1DifferencedReduced);
            if (inters && inters.length > 0) {
                top1ResutlArrs.push(inters);
            }
        })

        let topMostIntsectResultArrs = []

        topMostMappedArrs.forEach(theArr => {
            let inters = intersection(theArr, topMostTop1Intersected);
            let tempArr = [];
            if (inters && inters.length > 0) {
                let i = 0;
                while (i < inters.length) {
                    tempArr.push(inters[i]);
                    if (inters[i + 1] !== inters[i] + 1) {
                        topMostIntsectResultArrs.push(tempArr);
                        tempArr = [];
                    }
                    i++;
                }
                // topMostIntsectResultArrs.push(inters);
            }
        })


        let top1IntsectResultArrs = []

        top1MappedArrs.forEach(theArr => {
            let inters = intersection(theArr, topMostTop1Intersected);
            let tempArr = [];
            if (inters && inters.length > 0) {
                let i = 0;
                while (i < inters.length) {
                    tempArr.push(inters[i]);
                    if (inters[i + 1] !== inters[i] + 1) {
                        top1IntsectResultArrs.push(tempArr);
                        tempArr = [];
                    }
                    i++;
                }
                // topMostIntsectResultArrs.push(inters);
            }
        })
        enddate = new Date();
        // console.log("ms elapsed 2:", Math.abs(startdate.getTime() - enddate.getTime()));
        resultIntersected =
            union(
                topMostIntsectResultArrs.map(arr => arr[0] + "_" + arr[arr.length - 1]),
                top1IntsectResultArrs.map(arr => arr[0] + "_" + arr[arr.length - 1])
            ).map(startEndIdx => {
                let splits = startEndIdx.split("_");
                return {
                    start: parseInt(splits[0]),
                    end: parseInt(splits[1]),
                    type: "topMost+top1",
                    text: theEng.substring(parseInt(splits[0]), parseInt(splits[1]) + 1)
                }
            })
        // topMostResutlArrs.forEach(entry => console.log(theEng.substring(entry[0], entry[entry.length - 1] + 1)));

        topMostResultArr = topMostResutlArrs.map(entry => {
            return {
                start: entry[0],
                end: entry[entry.length - 1],
                type: "topMost",
                text: theEng.substring(entry[0], entry[entry.length - 1] + 1)
            }
        });

        // console.log("-------------------->")
        // top1ResutlArrs.forEach(entry => {
        //   console.log(theEng.substring(entry[0], entry[entry.length - 1] + 1))
        // });

        top1ResultArr = top1ResutlArrs.map(entry => {
            return {
                start: entry[0],
                end: entry[entry.length - 1],
                type: "top1",
                text: theEng.substring(entry[0], entry[entry.length - 1] + 1)
            }
        });
        orderedAllPhrasesSplitsArr = orderBy(topMostResultArr.concat(top1ResultArr).concat(resultIntersected), (phraseSplit) => phraseSplit.start, "asc");
    } else if(theProps.theLijuEntry.pickedPhrasesTopMost&&theProps.theLijuEntry.pickedPhrasesTopMost?.length>0) {
        topMostResultArr = [...theProps.theLijuEntry.pickedPhrasesTopMost].map(pickedPhraseTopMost => {
            return {
                start: pickedPhraseTopMost.startWordMark.startIdx,
                end: pickedPhraseTopMost.endWordMark.startIdx + pickedPhraseTopMost.endWordMark.word.length - 1,
                type: "topMost",
                text: theEng.substring(pickedPhraseTopMost.startWordMark.startIdx, pickedPhraseTopMost.endWordMark.startIdx + pickedPhraseTopMost.endWordMark.word.length - 1 + 1)
            }
        });

        orderedAllPhrasesSplitsArr = orderBy(topMostResultArr, (phraseSplit) => phraseSplit.start, "asc");
    }else{
        orderedAllPhrasesSplitsArr = [{start:0,end:theEng.length-1,type:"normal",text:theEng}]
    }

    /**
     * pickedPhrases 处理完splits后 整个句子的其他部分
     */

    let normalArr = [];
    orderedAllPhrasesSplitsArr.forEach((entry, idx) => {
        if (idx === 0 && entry.start !== 0) {
            normalArr.push({
                start: 0,
                end: entry.start - 1, type: "normal", text: theEng.substring(0, entry.start - 1 + 1)
            })
        }

        if (orderedAllPhrasesSplitsArr[idx + 1] && entry.end + 1 !== orderedAllPhrasesSplitsArr[idx + 1]?.start) {
            normalArr.push({
                start: entry.end + 1,
                end: orderedAllPhrasesSplitsArr[idx + 1].start - 1,
                type: "normal",
                text: theEng.substring(entry.end + 1, orderedAllPhrasesSplitsArr[idx + 1].start - 1 + 1)
            })
        }

        if (idx === orderedAllPhrasesSplitsArr.length - 1 && (entry.end + 1) !== theEng.length) {
            normalArr.push({
                start: entry.end + 1,
                end: theEng.length - 1, type: "normal", text: theEng.substring(entry.end + 1, theEng.length - 1 + 1)
            })
        }
    })

    clearAndPushAll(finalOrderedSplitsArr,orderBy(orderedAllPhrasesSplitsArr.concat(normalArr), (phraseSplit) => phraseSplit.start, "asc"));
    if (finalOrderedSplitsArr && finalOrderedSplitsArr?.length > 0 && finalOrderedSplitsArr.map(split => split.text).join("") !== theEng) {
        throw new Error("build finalOrderedSplitsArr errored in .....");
    }

    enddate = new Date();
    // console.log("ms elapsed 3:", Math.abs(startdate.getTime() - enddate.getTime()));







    /**
     * words 处理
     *
     */
    let pickedWordsTopMostArr = orderBy(theProps.theLijuEntry.pickedWordsTopMost.map((pickedWordTopMost,idx) => {
        return {
            startIdx: pickedWordTopMost.startWordMark.startIdx,
            text: pickedWordTopMost.startWordMark.word,
            wordRankLevel: "topWord"
        }
    }), (theWord) => theWord.startIdx, "asc");

    pickedWordsTopMostArr.forEach((pickedWordTopMost,idx) => {
        let preTopMostWord = pickedWordsTopMostArr[idx-1];
        // pickedWordTopMost.idx = idx;
        // pickedWordTopMost.preEnd = preTopMostWord?(preTopMostWord&&preTopMostWord.startIdx+preTopMostWord.text.length+1):-1;
        // pickedWordTopMost.prestart = preTopMostWord?(preTopMostWord&&preTopMostWord.startIdx):-1;
        // pickedWordTopMost.prelength = preTopMostWord?(preTopMostWord.text.length):-1;
        pickedWordTopMost.hasAdjoinWords = preTopMostWord&&preTopMostWord.startIdx+preTopMostWord.text.length+1===pickedWordTopMost.startIdx;
    })


    // idx:idx,
    //     preEnd:preTopMostWord?(preTopMostWord&&preTopMostWord.startWordMark.startIdx+pickedWordTopMost.startWordMark.word.length+1):-1,
    //     hasAdjoinWords:preTopMostWord&&preTopMostWord.startWordMark.startIdx+pickedWordTopMost.startWordMark.word.length+1===pickedWordTopMost.startWordMark.startIdx

    pickedWordsTopMostArr.forEach(theWord => {
        finalOrderedSplitsArr.forEach(theNodeSplit => {
            if (theWord.startIdx >= theNodeSplit.start && (theWord.startIdx + theWord.text.length) <= theNodeSplit.end + 1) {
                if (!theNodeSplit.wordsArr) {
                    theNodeSplit.wordsArr = []
                }
                theNodeSplit.wordsArr.push(theWord)
            }
        })
    })


    finalOrderedSplitsArr.forEach(theNodeSplit => {
        let intervalNodeArr = [];
        if (theNodeSplit.wordsArr && theNodeSplit.wordsArr?.length > 0) {

            theNodeSplit.wordsArr.forEach((theWord, idx) => {
                if (idx === 0 && theWord.startIdx !== theNodeSplit.start) {
                    intervalNodeArr.push({
                        startIdx: 0,
                        text: theEng.substring(theNodeSplit.start, theWord.startIdx)
                    });
                }

                if (idx === theNodeSplit.wordsArr.length - 1 && (theWord.startIdx + theWord.text.length) !== theNodeSplit.end + 1) {
                    intervalNodeArr.push({
                        startIdx: theWord.startIdx + theWord.text.length,
                        text: theEng.substring(theWord.startIdx + theWord.text.length, theNodeSplit.end + 1)
                    });
                }

                if (theNodeSplit.wordsArr[idx + 1]) {
                    intervalNodeArr.push({
                        startIdx: theWord.startIdx + theWord.text.length,
                        text: theEng.substring(theWord.startIdx + theWord.text.length, theNodeSplit.wordsArr[idx + 1].startIdx)
                    });
                }
            })

            let orderedArr = orderBy(intervalNodeArr.concat(theNodeSplit.wordsArr), theNode => theNode.startIdx, "asc");
            if (orderedArr.map(node => node.text).join("") !== theNodeSplit.text) {
                throw new Error("build orderedArr errored in , " + theNodeSplit.text);
            }

            theNodeSplit.subSplits = orderedArr;
        }
    })

    enddate = new Date();
    // console.log("ms elapsed 1:", Math.abs(startdate.getTime() - enddate.getTime()));

})


</script>

<template>

  <el-text>
      <b>·</b>
      <span v-for="(split,idx) in finalOrderedSplitsArr" :key="split.start" :class="{topMost:split.type&&split.type===`topMost`}">
          <span v-if="split.subSplits&&split.subSplits?.length>0">
            <span v-for="(subSplit,idx) in split.subSplits">
                <b v-if="subSplit.wordRankLevel&&subSplit.wordRankLevel===`topWord`">
                    <sub style="font-size: 5px" v-if="subSplit.startIdx!==0&&subSplit.hasAdjoinWords">♠</sub>{{subSplit.text}}
                </b>
                <span v-else>
                    {{subSplit.text}}
                </span>

            </span>
          </span>
          <span v-else>
            {{split.text}}
          </span>
      </span>
      <div>
          {{ theLijuEntry.chi }}
      </div>

  </el-text>
<!--  {{theLijuEntry.pickedPhrasesTopMost}}-->
<!--  {{finalOrderedSplitsArr}}-->
</template>

<style scoped>

.topMost{
    /*background-color: var(--tagbuttons-group-color-bg-color-normal-group1);*/
    background-color: var(--tagbuttons-group-color-bg-color-darker2-group1);
    border:1px solid;
    border-radius: 3px;
    padding: 1px 2px;
    /*border-color: var(--tagbuttons-group-color-border-color-group1);*/
    border-color: var(--tagbuttons-group-color-border-darker-color-group1);
    /*color:var(--tagbuttons-group-color-text-color-default);*/
}
</style>